import React, { useState, useCallback } from 'react';
import Cropper from 'react-easy-crop';
import { Card, Upload, Button, Slider, Form, InputNumber, Row, Col, message, Image, Space } from 'antd';
import { UploadOutlined, DownloadOutlined, RotateLeftOutlined, RotateRightOutlined, ZoomInOutlined, ZoomOutOutlined } from '@ant-design/icons';
import type { RcFile } from 'antd/es/upload';
import type { Area } from 'react-easy-crop';

const ImageCropper: React.FC = () => {
  const [image, setImage] = useState<string | null>(null);
  const [fileName, setFileName] = useState<string>(''); // 添加文件名状态
  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [rotation, setRotation] = useState(0);
  const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);
  const [croppedImage, setCroppedImage] = useState<string | null>(null);
  const [width, setWidth] = useState(300);
  const [height, setHeight] = useState(300);
  const [cropX, setCropX] = useState(0);
  const [cropY, setCropY] = useState(0);

  const handleUpload = (file: RcFile) => {
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isJpgOrPng) {
      message.error('只能上传 JPG/PNG 格式的图片!');
      return false;
    }
    
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error('图片大小不能超过 2MB!');
      return false;
    }
    
    const reader = new FileReader();
    reader.onload = (e) => {
      setImage(e.target?.result as string);
      setFileName(file.name); // 保存文件名
      setCroppedImage(null);
    };
    reader.readAsDataURL(file);
    
    return false;
  };

  const onCropComplete = useCallback((_croppedArea: Area, croppedAreaPixels: Area) => {
    setCroppedAreaPixels(croppedAreaPixels);
    // 更新裁剪位置XY参数
    setCropX(Math.round(croppedAreaPixels.x));
    setCropY(Math.round(croppedAreaPixels.y));
  }, []);

  const createImage = (url: string): Promise<HTMLImageElement> =>
    new Promise((resolve, reject) => {
      const image = new window.Image();
      image.addEventListener('load', () => resolve(image));
      image.addEventListener('error', (error: ErrorEvent) => reject(error));
      image.setAttribute('crossOrigin', 'anonymous');
      image.src = url;
    });

  const getCroppedImg = async (imageSrc: string, pixelCrop: Area, rotation = 0): Promise<string> => {
    const image = await createImage(imageSrc);
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    if (!ctx) {
      throw new Error('无法创建 canvas 上下文');
    }

    const maxSize = Math.max(image.width, image.height);
    const safeArea = 2 * ((maxSize / 2) * Math.sqrt(2));

    canvas.width = safeArea;
    canvas.height = safeArea;

    ctx.translate(safeArea / 2, safeArea / 2);
    ctx.rotate((rotation * Math.PI) / 180);
    ctx.translate(-safeArea / 2, -safeArea / 2);

    ctx.drawImage(
      image,
      safeArea / 2 - image.width * 0.5,
      safeArea / 2 - image.height * 0.5
    );

    const data = ctx.getImageData(0, 0, safeArea, safeArea);

    canvas.width = pixelCrop.width;
    canvas.height = pixelCrop.height;

    ctx.putImageData(
      data,
      Math.round(0 - safeArea / 2 + image.width * 0.5 - pixelCrop.x),
      Math.round(0 - safeArea / 2 + image.height * 0.5 - pixelCrop.y)
    );

    return canvas.toDataURL('image/jpeg');
  };

  const handleCrop = async () => {
    if (!image || !croppedAreaPixels) return;
    
    try {
      const croppedImageUrl = await getCroppedImg(image, croppedAreaPixels, rotation);
      setCroppedImage(croppedImageUrl);
      message.success('图片裁剪成功！');
    } catch (error) {
      message.error('裁剪图片时出错，请重试');
    }
  };

  const handleDownload = () => {
    if (!croppedImage) {
      message.warning('没有可下载的裁剪图片');
      return;
    }
    
    // 生成下载文件名
    const fileExtension = fileName.substring(fileName.lastIndexOf('.'));
    const baseName = fileName.substring(0, fileName.lastIndexOf('.'));
    const downloadName = `cropped-${baseName || 'image'}${fileExtension || '.jpeg'}`;
    
    const link = document.createElement('a');
    link.download = downloadName;
    link.href = croppedImage;
    link.target = '_blank';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    message.success('图片下载成功！');
  };

  const handleRotateLeft = () => {
    setRotation(prev => prev - 90);
  };

  const handleRotateRight = () => {
    setRotation(prev => prev + 90);
  };

  const handleZoomIn = () => {
    setZoom(prev => Math.min(prev + 0.1, 3));
  };

  const handleZoomOut = () => {
    setZoom(prev => Math.max(prev - 0.1, 1));
  };

  return (
    <Card title="图片裁剪工具" style={{ width: '100%' }}>
      <Row gutter={[16, 16]}>
        <Col span={12}>
          <Card title="上传图片" size="small">
            <Form layout="vertical">
              <Form.Item label="选择图片">
                <Upload 
                  beforeUpload={handleUpload} 
                  maxCount={1}
                  accept=".jpg,.jpeg,.png"
                  showUploadList={false}
                >
                  <Button icon={<UploadOutlined />}>点击上传</Button>
                </Upload>
              </Form.Item>
              
              {image && (
                <>
                  <Form.Item label="尺寸设置">
                    <Space>
                      <InputNumber 
                        addonBefore="宽度" 
                        value={width} 
                        onChange={(value) => value && setWidth(value)} 
                        min={50}
                        max={1000}
                      />
                      <InputNumber 
                        addonBefore="高度" 
                        value={height} 
                        onChange={(value) => value && setHeight(value)} 
                        min={50}
                        max={1000}
                      />
                    </Space>
                  </Form.Item>
                  
                  <Form.Item label="裁剪位置">
                    <Space>
                      <InputNumber 
                        addonBefore="X" 
                        value={cropX} 
                        onChange={(value) => {
                          if (value !== null) {
                            setCropX(value);
                            if (croppedAreaPixels) {
                              setCroppedAreaPixels({
                                ...croppedAreaPixels,
                                x: value
                              });
                              setCrop({ x: value, y: crop.y });
                            }
                          }
                        }}
                        min={0}
                        precision={0}
                      />
                      <InputNumber 
                        addonBefore="Y" 
                        value={cropY} 
                        onChange={(value) => {
                          if (value !== null) {
                            setCropY(value);
                            if (croppedAreaPixels) {
                              setCroppedAreaPixels({
                                ...croppedAreaPixels,
                                y: value
                              });
                              setCrop({ x: crop.x, y: value });
                            }
                          }
                        }}
                        min={0}
                        precision={0}
                      />
                    </Space>
                  </Form.Item>
                  
                  <Form.Item label="缩放">
                    <Slider 
                      min={0.1} 
                      max={3} 
                      step={0.01} 
                      value={zoom} 
                      onChange={setZoom}
                    />
                  </Form.Item>
                  
                  <Form.Item label="旋转">
                    <Slider 
                      min={-180} 
                      max={180} 
                      step={1} 
                      value={rotation} 
                      onChange={setRotation}
                    />
                  </Form.Item>
                  
                  <Space>
                    <Button onClick={handleRotateLeft} icon={<RotateLeftOutlined />}>
                      左转
                    </Button>
                    <Button onClick={handleRotateRight} icon={<RotateRightOutlined />}>
                      右转
                    </Button>
                    <Button onClick={handleZoomOut} icon={<ZoomOutOutlined />}>
                      缩小
                    </Button>
                    <Button onClick={handleZoomIn} icon={<ZoomInOutlined />}>
                      放大
                    </Button>
                    <Button type="primary" onClick={handleCrop}>
                      裁剪
                    </Button>
                  </Space>
                </>
              )}
            </Form>
          </Card>
        </Col>
        
        <Col span={12}>
          <Card title="预览区域" size="small">
            {image ? (
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
                <div style={{ 
                  position: 'relative', 
                  width: width, 
                  height: height, 
                  marginBottom: 20,
                  backgroundColor: '#fafafa'
                }}>
                  <Cropper
                    image={image}
                    crop={crop}
                    zoom={zoom}
                    rotation={rotation}
                    aspect={width / height}
                    onCropChange={setCrop}
                    onZoomChange={setZoom}
                    onRotationChange={setRotation}
                    onCropComplete={onCropComplete}
                    cropShape="rect"
                    showGrid
                  />
                </div>
                
                {croppedImage && (
                  <div style={{ textAlign: 'center' }}>
                    <h4>裁剪结果:</h4>
                    <Image 
                      src={croppedImage} 
                      alt="Cropped" 
                      width={width / 2} 
                      height={height / 2} 
                    />
                    <br />
                    <Button 
                      type="primary" 
                      icon={<DownloadOutlined />} 
                      onClick={handleDownload}
                      style={{ marginTop: 10 }}
                    >
                      下载裁剪图片
                    </Button>
                  </div>
                )}
              </div>
            ) : (
              <div style={{ 
                height: 300, 
                display: 'flex', 
                justifyContent: 'center', 
                alignItems: 'center',
                border: '1px dashed #ccc'
              }}>
                <span>请先上传一张图片</span>
              </div>
            )}
          </Card>
        </Col>
      </Row>
    </Card>
  );
};

export default ImageCropper;